
package com.liao.badminton.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.github.pagehelper.PageInfo;
import com.liao.badminton.code.PageParam;
import com.liao.badminton.code.ProjectException;
import com.liao.badminton.code.RespCodeMessage;
import com.liao.badminton.code.ResponseRest;
import com.liao.badminton.code.util.CheckUtil;
import com.liao.badminton.code.util.EntityUtils;
import com.liao.badminton.code.validation.Delete;
import com.liao.badminton.code.validation.FindDetail;
import com.liao.badminton.code.validation.Insert;
import com.liao.badminton.code.validation.Update;
import com.liao.badminton.dto.ApplyJoinGroupDto;
import com.liao.badminton.dto.ImportRecordDto;
import com.liao.badminton.dto.UserGroupRefDto;
import com.liao.badminton.entity.JoinGroupApply;
import com.liao.badminton.entity.UserGroupRef;
import com.liao.badminton.service.UserGroupRefService;
import com.liao.badminton.vo.BoutStatVo;
import com.liao.badminton.vo.JoinGroupApplyVo;
import com.liao.badminton.vo.StatVo;
import com.liao.badminton.vo.UserGroupRefVo;
import io.swagger.annotations.ApiParam;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;

import static cn.hutool.core.util.ObjectUtil.isNotEmpty;

/**
 * @author liaocheng
 * @date 2024-11-01
 * description:用户和群关系
 */
@RestController
@RequestMapping(value = "/userGroupRef")
@PreAuthorize("@ss.hasPermission('userGroupRef')")//权限管理;
public class UserGroupRefController {

    @Resource
    private UserGroupRefService userGroupRefService;

    /**
     * 新增userGroupRef
     */
    @RequestMapping(value = "/add")
    @PreAuthorize("@ss.hasPermission('userGroupRef:add')")//权限管理;
    public ResponseRest<Long> add(@RequestBody @Validated(Insert.class) UserGroupRefDto userGroupRef) throws ProjectException {
        return userGroupRefService.saveUserGroupRef(userGroupRef);
    }

    /**
     * 批量删除
     */
    @RequestMapping(value = "/deletes")
    @PreAuthorize("@ss.hasPermission('userGroupRef:deletes')")//权限管理;
    public ResponseRest<Boolean> deletes(@RequestBody @Validated(Delete.class) UserGroupRefDto param) throws ProjectException {
        return userGroupRefService.deletesUserGroupRef(param);
    }

    /**
     * 修改userGroupRef
     */
    @RequestMapping(value = "/update")
    @PreAuthorize("@ss.hasPermission('userGroupRef:update')")//权限管理;
    public ResponseRest<Boolean> update(@RequestBody @Validated(Update.class) UserGroupRefDto param) throws ProjectException {
        return userGroupRefService.updateUserGroupRef(param);
    }

    @RequestMapping(value = "/findDetail")
    @PreAuthorize("@ss.hasPermission('UserGroupRef:findDetail')")//权限管理;
    public ResponseRest<UserGroupRefVo> findDetail(@RequestBody @Validated(FindDetail.class) UserGroupRefDto param) throws ProjectException {
        return userGroupRefService.findDetail(param);
    }

    @RequestMapping(value = "/findOneCurrentIdGroupId")
    @PreAuthorize("@ss.hasPermission('UserGroupRef:findOneCurrentIdGroupId')")//权限管理;
    public ResponseRest<UserGroupRefVo> findOneCurrentIdGroupId(@RequestBody UserGroupRefDto param)throws ProjectException {
        return userGroupRefService.findOneCurrentIdGroupId(param);
    }

    /**
     * 用户主页（总统计：所有加入的群）
     */
    @RequestMapping(value = "/allStat")
    @PreAuthorize("@ss.hasPermission('userGroupRef:allStat')")//权限管理;
    public ResponseRest<StatVo> allStat(@RequestParam(name = "groupId", required = false) Long groupId) throws ProjectException {
        return userGroupRefService.allStat(groupId);
    }

    /**
     * 获取群成员列表(用户主页)
     * 只传groupId时，获取该群所有成员
     * 只传userId时，获取该用户加入的所有群-不传就获取当前用户
     */
    @RequestMapping(value = "/list")
    @PreAuthorize("@ss.hasPermission('userGroupRef:list')")//权限管理;
    public ResponseRest<PageInfo<UserGroupRefVo>> list(@RequestBody PageParam<UserGroupRefDto> body) throws ProjectException {
        return userGroupRefService.findUserGroupRefByPageParam(body);
    }

    /**
     * 设置用户为管理-转让群主,退群deleted =-1
     * adminType = 0:普通成员（同意入群时传）,1:管理员,2:群主
     *
     * @param param 需要id和adminType
     */
    @RequestMapping(value = "/setManager")
    @PreAuthorize("@ss.hasPermission('userGroupRef:setManager')")//权限管理;
    @Transactional
    public ResponseRest<Boolean> setManager(@RequestBody UserGroupRefDto param) throws ProjectException {
        return userGroupRefService.setManager(param);
    }

    /**
     * 用户申请加入群组（分享码或群id）
     *
     * @param param
     * @return
     */
    @RequestMapping(value = "/applyJoinGroup")
    @PreAuthorize("@ss.hasPermission('userGroupRef:applyJoinGroup')")//权限管理;
    @Transactional
    public ResponseRest<String> applyJoinGroup(@RequestBody ApplyJoinGroupDto param) throws ProjectException {
        return userGroupRefService.applyJoinGroup(param);
    }

    /**
     * 获取申请加入的群列表
     */
    @RequestMapping(value = "/findApplyJoinGroupList")
    @PreAuthorize("@ss.hasPermission('userGroupRef:findApplyJoinGroupList')")//权限管理;
    public ResponseRest<PageInfo<JoinGroupApplyVo>> findApplyJoinGroupList(@RequestBody PageParam<JoinGroupApply> body) throws ProjectException {
        return userGroupRefService.findApplyJoinGroupList(body);
    }

    /**
     * 入群申请处理
     */
    @RequestMapping(value = "/joinAppHandle")
    @PreAuthorize("@ss.hasPermission('userGroupRef:joinAppHandle')")//权限管理;
    public ResponseRest<Boolean> joinAppHandle(@RequestParam(name = "id") Long id,
                                                             @ApiParam(value = "1:同意,2:拒绝") @RequestParam(name = "status") Integer status

    ) throws ProjectException {
        return userGroupRefService.joinAppHandle(id, status);
    }

    /**
     * 下载群成员模板文件
     */
    @GetMapping("/download")
    @PreAuthorize("@ss.hasPermission('file/download')")
    public void download(HttpServletResponse response) {
        Set<Map<String, Object>> headers = new HashSet<>();
        TreeMap<String, Object> list = new TreeMap<>();
        list.put("群成员姓名", null);
        list.put("角色：0:普通成员,1:管理员,2:群主（不填就是0）", null);
        list.put("总局数", null);
        list.put("总胜局数", null);
        list.put("总负局数", null);
        list.put("总得分（胜局-负局）", null);
        list.put("总奖励（赢水数量）", null);
        headers.add(list);
        OutputStream out = null;
        try (ExcelWriter writer = ExcelUtil.getWriter()) {
            writer.write(headers, true);// 写入数据
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("群成员模板.xlsx", "UTF-8"));
            out = response.getOutputStream();// 获取流
            writer.flush(out, true); // 将数据流输出到文件
        } catch (IOException e) {
            e.printStackTrace();
        }
        IoUtil.close(out);// 流的操作要关闭
    }

    /**
     * 上传文件录入
     *
     * @param file
     * @param groupId
     * @return
     */
    @PostMapping(name = "/upload")
    @PreAuthorize("@ss.hasPermission('importRecord:upload')")
//    @Transactional
    public ResponseRest<Boolean> upload(@RequestPart("files") MultipartFile file,
                                        @RequestParam(name = "groupId") Long groupId) {
        if (!file.isEmpty()) {
            try {
                String name = file.getOriginalFilename();
                assert name != null;
                Boolean isXlsx = name.endsWith(".xlsx") || name.endsWith(".xls");
                if (isXlsx) {
                    List<String> dbUserNames = userGroupRefService.findUserNamesByGroupId(groupId);
                    List<String> hasDb = CollectionUtil.newArrayList();
                    ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
                    List<UserGroupRef>  list = CollectionUtil.newArrayList();
                    Map<String,List<Integer>>  errors = new HashMap<>();
                    Map<String,Integer> headers = new HashMap<>();
                    List<Map<String, Object>> readAll = reader.readAll();
                    for (Map<String, Object> row : readAll) {
                        //key值查看下载模样：com.liao.badminton.controller.FileDealController.download
                        Object userName = row.get("群成员姓名");
                        String userNameString = userName.toString();
                        Object groupType = row.get("角色：0:普通成员,1:管理员,2:群主（不填就是0）");
                        Object totalBout = row.get("总局数");
                        Object winBout = row.get("总胜局数");
                        Object loseBout = row.get("总负局数");
                        Object totalScore = row.get("总得分（胜局-负局）");
                        Object totalReward = row.get("总奖励（赢水数量）");
                        if (dbUserNames.contains(userNameString)) {
                            hasDb.add(userNameString);
                            continue;
                        }
                        if (headers.containsKey(userNameString)) {
                            if (errors.containsKey(userNameString)) {
                                errors.get(userNameString).add(readAll.indexOf(row)+2);
                            }else {
                                List<Integer> list1 = new ArrayList<>();
                                list1.add(headers.get(userNameString));;
                                list1.add(readAll.indexOf(row)+2);;
                                errors.put(userNameString, list1);
                            }
                        }else {
                            headers.put(userNameString, readAll.indexOf(row)+2);
                        }
                        CheckUtil.checkValue(userName, "群成员姓名不能为空");
                        UserGroupRef userGroupRef = new UserGroupRef();
                        userGroupRef.setUserName(userNameString);
                        userGroupRef.setGroupId(groupId);
                        userGroupRef.setAdminType(groupType == null ? null : Integer.parseInt(groupType.toString()));
                        userGroupRef.setTotalBout(totalBout == null ? null : Integer.parseInt(totalBout.toString()));
                        userGroupRef.setWinBout(winBout == null ? null : Integer.parseInt(winBout.toString()));
                        userGroupRef.setLoseBout(loseBout == null ? null : Integer.parseInt(loseBout.toString()));
                        userGroupRef.setTotalScore(totalScore == null ? null : Integer.parseInt(totalScore.toString()));
                        userGroupRef.setAwardCoin(totalReward == null ? null : new BigDecimal(totalReward.toString()));
                        EntityUtils.setCreatAndUpdateInfo(userGroupRef);
                        list.add(userGroupRef);
                    }
                    if (isNotEmpty(errors)) {
                        StringBuilder err = new StringBuilder();
                        errors.forEach((k,v)->{
                            err.append("第").append(v).append("行，").append(k).append("重复");
                        });
                        return ResponseRest.fail("upload", err.toString());
                    }
                    if (list.size() > 0) {
                        userGroupRefService.saveBatch(list);
                    }
                    if (hasDb.size() > 0) {
                        StringBuilder sb = new StringBuilder();
                        hasDb.forEach(s -> sb.append(s).append("\n"));
                        return ResponseRest.suc("upload", "上传成功！！以下用户已存在,导入将忽略：\n" + sb.toString());
                    }
                    return ResponseRest.suc("upload", "上传成功！！");
                }
            } catch (IOException e) {
                ProjectException.newException(RespCodeMessage.HANDLE_FILE_UPLOAD_ERROR, e.getMessage());
            }
        }
        return ResponseRest.suc("upload", "上传失败！！");
    }

    public static void main(String[] args) {
        String a = "555";
        Set<String> headers = new HashSet<>();
        headers.add(a);
        headers.add(a);


    }

}
